package Operators;


import java.util.ArrayList;
import java.util.Iterator;

import States.WaterCupState;
import Templates.Operator;
import GUI.IntroducereDateCana;

public class WaterCupOperators {
	
	private static ArrayList<Operator<WaterCupState>> waterCupOperators=new ArrayList<Operator<WaterCupState>>();
	private static ArrayList<String> state =IntroducereDateCana.date;
	static int c1 ;
	static int c2 ;
	
	public static ArrayList<Operator<WaterCupState>> returnOperators()
	{
		Iterator<String> itr =  state.iterator();
		int[] v = new int[2];
		int i=0;
	    while(itr.hasNext()) {
	         String element = itr.next();
	         v[i++] = Integer.parseInt(element);
	    }
	    c1 = v[0];
	    c2 = v[1];
	    
	    waterCupOperators.removeAll(waterCupOperators);
		waterCupOperators.add(new Fill1());
		waterCupOperators.add(new Fill2());
		waterCupOperators.add(new Empty1());
		waterCupOperators.add(new Empty2());
		waterCupOperators.add(new Empty_1to2());
		waterCupOperators.add(new Empty_2to1());
		return waterCupOperators;
	}
	

	public static class Fill1 implements Operator<WaterCupState>{
		
		public int getOperatorNumber()
		{
			return 1;
		}
		public WaterCupState execute(WaterCupState s)
		{
				return new WaterCupState(c1,s.getCapacity2());

		}
		public boolean available(WaterCupState s)
		{
			if (s.getCapacity1()<c1)
			return true;
			else return false;
		}
		public String toString()
		{
			return "Filling first cup";
		}

	}
	
	public static class Fill2 implements Operator<WaterCupState>{
		public int getOperatorNumber()
		{
			return 2;
		}

		public WaterCupState execute(WaterCupState s)
		{
				return new WaterCupState(s.getCapacity1(),c2);

		}
		
		public boolean available(WaterCupState s)
		{
			if (s.getCapacity2()<c2)
			return true;
			else return false;
		}
		public String toString()
		{
			return "Filling second cup";
		}

	}
	
	public static class Empty1 implements Operator<WaterCupState>{

		public int getOperatorNumber()
		{
			return 3;
		}
		public WaterCupState execute(WaterCupState s)
		{

				return new WaterCupState(0,s.getCapacity2());

		}
		public boolean available(WaterCupState s)
		{
			if (s.getCapacity1()>0)
			return true;
			else return false;
		}
		public String toString()
		{
			return "Empting first cup";
		}

	}
	
	public static class Empty2 implements Operator<WaterCupState>{

		public int getOperatorNumber()
		{
			return 4;
		}
		public WaterCupState execute(WaterCupState s)
		{

				return new WaterCupState(s.getCapacity1(),0);

		}
		public boolean available(WaterCupState s)
		{
			if (s.getCapacity2()>0)
			return true;
			else return false;
		}
		public String toString()
		{
			return "Empting second cup";
		}

	}
	
	public static class Empty_1to2 implements Operator<WaterCupState>{

		public int getOperatorNumber()
		{
			return 5;
		}
		public WaterCupState execute(WaterCupState s)
		{

			int aux1=min(c2,s.getCapacity1()+s.getCapacity2());
			int aux2=Math.abs(c1-(s.getCapacity1()+s.getCapacity2()));
			WaterCupState s2=new WaterCupState(aux2,aux1);
			return s2;
		}
		public boolean available(WaterCupState s)
		{
			if (s.getCapacity2()<c2 && s.getCapacity1()>0)
			return true;
			else return false;
		}
		public int min(int a,int b)
		{		
			if (a<b) return a; else return b;
		}
		public String toString()
		{
			return "Filling second using first cup";
		}

		
	}
	
	public static class Empty_2to1 implements Operator<WaterCupState>{
		
		
		public int getOperatorNumber()
		{
			return 6;
		}
		public WaterCupState execute(WaterCupState s)
		{
			
			int aux1=min(c1,s.getCapacity1()+s.getCapacity2());
			int aux2=0;
			if (s.getCapacity2()<c1-s.getCapacity1()) aux2=0;
			else aux2=Math.abs(c1-(s.getCapacity1()+s.getCapacity2()));
			WaterCupState s2=new WaterCupState(aux1,aux2);
			return s2;

		}
		public boolean available(WaterCupState s)
		{
			if (s.getCapacity2()>0 && s.getCapacity1()<c1)
			return true;
			else return false;
		}
		public int min(int a,int b)
		{		
			if (a<b) return a; else return b;
		}
		public String toString()
		{
			return "Filling first using second cup";
		}

	}
	public static class InitialState implements Operator<WaterCupState>
	{
		public String toString(){
	
			return "Initial State";
		}
		
		public int getOperatorNumber()
		{
			return 0;
		}
		
	
		public WaterCupState execute(WaterCupState s)
		{
			return null;
		}
	
		public boolean available(WaterCupState s)
		{
			return false;
		
		}
	}

}
